package com.baymax.lib.replace

import com.baymax.test.scene.replace.ReplaceListener

/**
 * 内容替换功能抽象类
 */
abstract class ReplacerFunction<T,R> {
    //替换规则map
    private val replacerRule = mutableMapOf<R,(T) -> T>()

    /**
     * 遍历符合规则的内容
     * 替换至指定内容返回
     * 无对应规则的内容
     * 返回原始内容
     */
    fun replace(t:T): T  = if (replacerRule.isNotEmpty()) replace(t,find(t,::finder),::replacer) else t

    /**
     * 添加替换规则
     */
    fun add(key:R, rule:(T)->T):ReplacerFunction<T,R>{
        replacerRule[key] = rule
        return this
    }

    /**
     * 移除替换规则
     */
    fun remove(key:R):ReplacerFunction<T,R>{
        replacerRule.remove(key)
        return this
    }

    /**
     * 清除所有的替换规则
     */
    fun clear(){
        replacerRule.clear()
    }

    /**
     * 遍历所有符合规则的内容，进行替换
     */
    private fun replacer(t:T, list:List<R>):T{
        var value = t;
        list.forEach {
            value = listener.beforeReplaceHandle(it,value)
            value = replacerRule[it]?.invoke(value)?:value
            value = listener.afterReplaceHandle(it,value)
        }
        return value
    }

    /**
     * 收集所有符合规则的内容
     */
    private fun find(t:T,filter:(T) -> List<R>): List<R> = filter.invoke(t)

    /**
     * 按规则将原始内容进行替换
     */
    private fun replace(t:T, list: List<R>, rule:(T, List<R>) -> T):T = rule.invoke(t,list)

    /**
     * 定义规则，收集符合规则的内容
     */
    abstract fun finder(t:T):List<R>

    /**
     * 规则替换拦截处理器
     */
    var listener: ReplaceListener<T, R> = object: ReplaceListener<T, R> {
        override fun beforeReplaceHandle(key: R, t: T): T  = t

        override fun afterReplaceHandle(key: R, t: T): T  = t
    }

    fun setReplaceListener(l: ReplaceListener<T, R>?){
        l?.let {
            listener = l
        }
    }

}